<template>
  <!-- 拖拽预览元素 -->
  <div
      v-if="isDragging"
      class="drag-preview"
      :style="{
      left: `${dragPosition.x}px`,
      top: `${dragPosition.y}px`
    }"
  >
    {{ draggedItem.age }}
  </div>

  <!-- 第一个Swiper -->
  <swiper
      ref="swiper1"
      class="swiper_class"
      :modules="modules"
      :slides-per-view="6"
      :space-between="10"
      navigation
      :scrollbar="{ draggable: false }"
      :allow-touch-move="false"
      @mouseenter="handleSwiperEnter('data1')"
  >
    <swiper-slide
        v-for="(item, index) in data1"
        :key="item.index"
        :data-index="index"
    >
      <div
          class="box"
          @mousedown="startDrag($event, item, 'data1')"
      >
        {{ item.age }}
      </div>
    </swiper-slide>
  </swiper>

  <div class="center_conter"></div>

  <!-- 第二个Swiper -->
  <swiper
      ref="swiper2"
      class="swiper_class"
      :modules="modules"
      :slides-per-view="6"
      :space-between="10"
      navigation
      :scrollbar="{ draggable: false }"
      :allow-touch-move="false"
      @mouseenter="handleSwiperEnter('data2')"
  >
    <swiper-slide
        v-for="(item, index) in data2"
        :key="item.index"
        :data-index="index"
    >
      <div
          class="box"
          @mousedown="startDrag($event, item, 'data2')"
      >
        {{ item.age }}
      </div>
    </swiper-slide>
  </swiper>
</template>

<script setup>
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Navigation } from 'swiper/modules'
import 'swiper/css'
import 'swiper/css/navigation'
import { ref, onUnmounted } from "vue"

const modules = [Navigation]

// 数据
const data1 = ref([
  {index:1, age: 10},
  {index:2, age: 11},
  {index:3, age: 12},
  {index:4, age: 13},
  {index:5, age: 14},
  {index:6, age: 15},
  {index:7, age: 16},
  {index:8, age: 17},
  {index:9, age: 18}
])

const data2 = ref([
  {index:1, age: 20},
  {index:2, age: 21},
  {index:3, age: 22},
  {index:4, age: 23},
  {index:5, age: 24},
  {index:6, age: 25},
  {index:7, age: 26},
  {index:8, age: 27},
  {index:9, age: 28}
])

// Swiper实例引用
const swiper1 = ref(null)
const swiper2 = ref(null)

// 拖拽状态
const isDragging = ref(false)
const draggedItem = ref(null)
const dragPosition = ref({ x: 0, y: 0 })
const sourceList = ref('')
const targetList = ref('')

// 开始拖拽
const startDrag = (event, item, listName) => {
  isDragging.value = true
  draggedItem.value = {...item} // 克隆对象
  sourceList.value = listName
  dragPosition.value = {
    x: event.clientX,
    y: event.clientY
  }
  // 添加全局鼠标事件
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

// 鼠标移动处理
const handleMouseMove = (event) => {
  if (!isDragging.value) return

  dragPosition.value = {
    x: event.clientX,
    y: event.clientY
  }
}

// 鼠标进入Swiper区域
const handleSwiperEnter = (listName) => {
  if (isDragging.value) {
    targetList.value = listName
  }

}

// 找到最近的Slide索引
const findNearestSlideIndex = (swiperInstance, clientX) => {
  if (!swiperInstance || !swiperInstance.value) return -1

  const slides = swiperInstance.value.$el.querySelectorAll('.swiper-slide')
  // 无穷大
  let minDistance = Infinity
  let nearestIndex = -1
  slides.forEach((slide, index) => {
    const rect = slide.getBoundingClientRect()
    const slideCenter = rect.left + rect.width / 2
    const distance = Math.abs(clientX - slideCenter)
    if (distance < minDistance) {
      minDistance = distance
      nearestIndex = index-1
    }
  })
  return nearestIndex
}

// 鼠标抬起处理
const handleMouseUp = (event) => {
  if (!isDragging.value || !targetList.value) {
    endDrag()
    return
  }

  // 检查是否拖拽到了另一个Swiper
  if (sourceList.value !== targetList.value) {
    const targetSwiper = targetList.value === 'data1' ? swiper1 : swiper2
    const nearestIndex = findNearestSlideIndex(targetSwiper, event.clientX)

    if (nearestIndex >= -1) {
      // 添加到目标列表的指定位置
      if (targetList.value === 'data1') {
        data1.value.splice(nearestIndex + 1, 0, draggedItem.value)
      } else {
        data2.value.splice(nearestIndex + 1, 0, draggedItem.value)
      }

      // 从源列表中移除
      if (sourceList.value === 'data1') {

        // 这个不能用item中的索引(index)做判断，必须要用data1、data2中的能确保唯一的值来做判断
        // 比如本例中的age在data1和data2中都是唯一的
        data1.value = data1.value.filter(item => item.age !== draggedItem.value.age)
      } else {
        data2.value = data2.value.filter(item => item.age !== draggedItem.value.age)
      }
    }
  }

  // 重置拖拽状态
  endDrag()
}

// 结束拖拽
const endDrag = () => {
  isDragging.value = false
  draggedItem.value = null
  sourceList.value = ''
  targetList.value = ''

  // 移除事件监听
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
}

// 组件卸载时清理
onUnmounted(() => {
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
})
</script>

<style scoped lang="less">
.swiper_class {
  width: 100%;
  .box {
    margin: 0 auto;
    width: 150px;
    height: 100px;
    background-color: lightblue;
    cursor: grab;
    user-select: none;
    transition: transform 0.1s;
    display: flex;
    align-items: center;
    justify-content: center;

    &:active {
      cursor: grabbing;
      transform: scale(0.95);
    }
  }
}

.center_conter {
  height: 300px;
  background-color: pink;
  margin: 20px 0;
}

.drag-preview {
  position: fixed;
  width: 150px;
  height: 100px;
  background-color: lightblue;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 1000;
  transform: translate(-50%, -50%);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
</style>
